package com.qqs.distributed.pointcut;

import com.qqs.distributed.advice.CacheAttributeSource;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.TransactionalProxy;

import java.lang.reflect.Method;

public class CacheAttributeSourcePointcut extends StaticMethodMatcherPointcut {
    private CacheAttributeSource cacheAttributeSource;

    public CacheAttributeSourcePointcut(CacheAttributeSource cacheAttributeSource) {
        setClassFilter(new CacheAttributeSourceClassFilter());
        this.cacheAttributeSource = cacheAttributeSource;
    }

    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        CacheAttributeSource cas = getCacheAttributeSource();
        return (cas == null || cas.getCacheAttribute(method, targetClass) != null);
    }

    public CacheAttributeSource getCacheAttributeSource() {
        return cacheAttributeSource;
    }

    public void setCacheAttributeSource(CacheAttributeSource cacheAttributeSource) {
        this.cacheAttributeSource = cacheAttributeSource;
    }

    private class CacheAttributeSourceClassFilter implements ClassFilter {
        @Override
        public boolean matches(Class<?> clazz) {

            if (TransactionalProxy.class.isAssignableFrom(clazz) ||
                    TransactionManager.class.isAssignableFrom(clazz) ||
                    PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
                return false;
            }

            CacheAttributeSource cas = getCacheAttributeSource();
            return (cas == null || cas.isCandidateClass(clazz));
        }
    }
}
